package persistencia;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Vector;

import model.Material;
import model.Proveedor;
import view.MaterialView;
import controller.Sistema;

public class AdministradorPersistenciaMateriales extends AdministradorPersistencia {
	
	private static AdministradorPersistenciaMateriales instancia;
	
	private String queryInsert = "insert into materiales (cuitProveedor,nombre,cantidadStock,puntoPedido,costo,estado) values (?,?,?,?,?,'ACTIVO')";
	private String queryUpdate = "update materiales set cuitProveedor=?,nombre=?,cantidadStock=?,puntoPedido=?,costo=? where codigoMaterial=?";
	private String queryDelete = "update materiales set estado='INACTIVO' where codigoMaterial=?";
	private String queryBuscar = "select * from materiales where codigoMaterial=? and estado='ACTIVO'";
	private String queryExiste = "select nombre from materiales where nombre=?";
	private String queryCodigoMaterial = "select Max(codigoMaterial) from materiales";
	private String queryActualizarStock = "update materiales set cantidadStock=((select cantidadStock from materiales where codigoMaterial=?)-?) where codigoMaterial=?";
	private String queryConsultarStock = "select cantidadStock,puntoPedido from materiales where codigoMaterial=?";
	private String queryVista = "select * from materiales where estado='ACTIVO'";
	private String queryItems = "select codigoPrenda from itemMateriales where codigoMaterial=?";
	
	private AdministradorPersistenciaMateriales(){

	}
	
	public static AdministradorPersistenciaMateriales getInstance(){
		if (instancia == null){
			instancia = new AdministradorPersistenciaMateriales();
		}
		return instancia;
	}

	public int insertarMaterial(String nombre, int stock, int ptoPed, float costo, long cuit) throws Exception {
		/*
		 * Devuelve el ID del material
		 * Caso contrario devuelve 0
		 */
		Connection con = super.getConnection();
		PreparedStatement ps = con.prepareStatement(queryInsert,Statement.RETURN_GENERATED_KEYS);
		ps.setLong(1, cuit);
		ps.setString(2, nombre);
		ps.setInt(3, stock);
		ps.setInt(4, ptoPed);
		ps.setFloat(5, costo);
		int codigoPrenda = 0;
		int rc = ps.executeUpdate();
		if (rc > 0){
			ResultSet key = ps.getGeneratedKeys();
			if (key.next()){
				codigoPrenda= key.getInt(1);
			}
		}
		con.close();
		return codigoPrenda;
	}
	
	public void actualizarMaterial(int codigo, String nombre, int stock, int ptoPed, float costo, long cuit) throws Exception {
		Connection con = super.getConnection();
		PreparedStatement ps = con.prepareStatement(queryUpdate);
		ps.setLong(1, cuit);
		ps.setString(2, nombre);
		ps.setInt(3, stock);
		ps.setInt(4, ptoPed);
		ps.setFloat(5, costo);
		ps.setInt(6, codigo);
		ps.execute();
		con.close();
	}
	

	public boolean eliminarMaterial(int codigo) throws Exception {
		/*
		 *  Devuelve verdadero si el material no es parte de ningun producto existente y lo elimina
		 *  Caso contrario devuelve falso
		 */
		// TODO falta considerar el caso en el que los productos vinculados esten inactivos
		Connection con = super.getConnection();
		PreparedStatement ps = con.prepareStatement(queryItems);
		ps.setInt(1, codigo);
		ResultSet rs = ps.executeQuery();
		if (!rs.next()){
			PreparedStatement s = con.prepareStatement(queryDelete);
			s.setInt(1, codigo);
			s.execute();
			con.close();
			return true;
		}
		con.close();
		return false;
	}
	

	public Material obtenerMaterial(int codigo) throws Exception {
		Connection con = super.getConnection();
		PreparedStatement ps = con.prepareStatement(queryBuscar);
		ps.setInt(1, codigo);
		ResultSet rs = ps.executeQuery();
		Material material = null;
		while (rs.next()){
			Proveedor prov = Sistema.getInstance().buscarProveedor(rs.getLong("cuitProveedor"));
			material = new Material(rs.getInt("codigoMaterial"),rs.getString("nombre"),
					rs.getInt("cantidadStock"),rs.getInt("puntoPedido"),rs.getFloat("costo"),prov);
		}
		con.close();
		return material;
	}
	
	public int obtenerCodigoMaterial(String nombre) throws Exception {
		// TODO Revisar si es realmente necesario
		Connection con = super.getConnection();
		PreparedStatement ps = con.prepareStatement(queryCodigoMaterial);
		ps.setString(1, nombre);
		ResultSet res = ps.executeQuery();
		int codigo=0;
		while (res.next()){
			codigo = res.getInt("codigoMaterial");
		}
		con.close();
		return codigo;
	}

	public boolean actualizarStockMaterial(int codigoMat, int cantidad) throws Exception {
		Connection con = super.getConnection();
		PreparedStatement ps = con.prepareStatement(queryActualizarStock);
		ps.setInt(1, codigoMat);
		ps.setInt(2, cantidad);
		ps.setInt(3, codigoMat);
		ps.execute();
		
		PreparedStatement ps2 = con.prepareStatement(queryConsultarStock);
		ps2.setInt(1, codigoMat);
		ResultSet res = ps2.executeQuery();
		boolean stockBajo = false;
		while (res.next()){
			if (res.getFloat("cantidadStock")<=res.getFloat("puntoPedido")){
				stockBajo = true;
			}
		}
		con.close();
		return stockBajo;
	}
	
	public Vector<MaterialView> obtenerVistaMateriales() throws Exception {
		Vector<MaterialView> lista = new Vector<MaterialView>();
		Connection con = super.getConnection();
		PreparedStatement ps = con.prepareStatement(queryVista);
		ResultSet res = ps.executeQuery();
		while (res.next()){
			MaterialView m = new MaterialView(
					res.getInt("codigoMaterial"),
					res.getString("nombre"),
					res.getInt("cantidadStock"),
					res.getInt("puntoPedido"),
					res.getFloat("costo"),
					res.getLong("cuitProveedor")
					);
			lista.add(m);
		}
		con.close();
		return lista;
	}

	public boolean existeNombreMaterial(String nombre) throws Exception {
		boolean rc = false;
		Connection con = super.getConnection();
		PreparedStatement ps = con.prepareStatement(queryExiste);
		ps.setString(1, nombre);
		ResultSet rs = ps.executeQuery();
		if (rs.next()){
			rc = true;
		}
		con.close();
		return rc;
	}

	
}
